package org.vacoor.nothing.web.controller;

import com.google.common.collect.ImmutableMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.vacoor.nothing.common.validation.Groups;
import org.vacoor.nothing.web.domain.Filters;
import org.vacoor.nothing.web.domain.Page;
import org.vacoor.nothing.web.domain.Pageable;
import org.vacoor.nothing.web.entity.Idable;
import org.vacoor.nothing.web.service.CrudService;
import org.vacoor.nothing.web.spring.inject.GenericAutowired;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 */
public abstract class AController<E extends Idable<ID>, ID extends Serializable> extends ConventionController<E, ID> {
    // spring 4 支持泛型注入, 可以使用 @Autowired, 但是 3.x 不支持, 可以在 BaseController 中使用(BaseController extends AController)
    @GenericAutowired
    protected CrudService<E, ID> crudService;

    /**
     * 分页过滤查询
     *
     * @param filters  过滤条件
     * @param pageable 分页排序
     * @return 分页结果
     */
    @ResponseBody
    @RequestMapping("list")
    public Page<E> list(Filters filters, Pageable pageable) {
        return crudService.findPage(filters, pageable);
    }

    /**
     * 新增一条记录
     *
     * @param e
     * @param binding
     */
    @ResponseBody
    @RequestMapping("create")
    public Map<String, Object> create(@Validated(Groups.C.class) E e, BindingResult binding) {
        if (binding.hasErrors()) {
            List<ObjectError> allErrors = binding.getAllErrors();
            ObjectError objectError = allErrors.get(0);
            return ImmutableMap.<String, Object>of("success", false, "message", objectError.getDefaultMessage());
        }
        crudService.save(e);
        return ImmutableMap.<String, Object>of(
                "success", true,
                "result", e
        );
    }

    /**
     * 更新
     *
     * @param e
     * @param binding
     * @return
     */
    @ResponseBody
    @RequestMapping("update")
    public Map<String, Object> update(@Validated(Groups.U.class) E e, BindingResult binding) {
        if (binding.hasErrors()) {
            List<ObjectError> errors = binding.getAllErrors();
            ObjectError error = errors.get(0);
            return ImmutableMap.<String, Object>of(
                    "success", false,
                    "message", error.getDefaultMessage()
            );
        }
        return ImmutableMap.<String, Object>of(
                "success", true,
                "result", e
        );
    }

    @ResponseBody
    @RequestMapping("delete")
    public Map<String, Object> delete(@RequestParam("id") ID[] ids) {
        crudService.delete(ids);
        return ImmutableMap.<String, Object>of(
                "success", true,
                "result", ids
        );
    }
}
